Qualcomm's QPNP PMIC Battery Management System driver

QPNP PMIC BMS provides interface to clients to read properties related
to the battery. It's main function is to calculate the State of Charge (SOC),
a 0-100 percentage representing the amount of charge left in the battery.

There are two required peripherals in the BMS driver, both implemented as
subnodes in the example. These peripherals must not be disabled if the BMS
device is to enabled:
- qcom,bms-bms : The main BMS device. Supports battery monitoring controls and
		sensors.
- qcom,bms-iadc : The BMS IADC peripheral in the IADC device. This is required
		to determine whether the BMS is using an internal or external
		rsense to accumulate the Coulomb Counter and read current.

Additionally, optional subnodes may be included:
- qcom,batt-pres-status : A subnode with a register address for the SMBB
		battery interface's BATT_PRES_STATUS register. If this node is
		added, then the BMS will try to detect offmode battery removal
		via the battery interface's offmode battery removal circuit.
- qcom,soc-storage-reg : A subnode with a register address to a spare PMIC
		register. If this node is included, then the BMS will store its
		shutdown SOC in the specified register instead of the default
		BMS data register.
- qcom,battery-data : A phandle to a node containing the available batterydata
		profiles. See the batterydata bindings documentation for more
		details.

Parent node required properties:
- compatible : should be "qcom,qpnp-bms" for the BM driver.
- qcom,r-sense-uohm : sensor resistance in in micro-ohms.
- qcom,v-cutoff-uv : cutoff voltage where the battery is considered dead in
			micro-volts.
- qcom,max-voltage-uv : maximum voltage for the battery in micro-volts.
- qcom,r-conn-mohm : connector resistance in milli-ohms.
- qcom,shutdown-soc-valid-limit : If the ocv upon restart is within this
			distance of the shutdown ocv, the BMS will try to force
			the new SoC to the old one to provide charge continuity.
			That is to say,
				if (abs(shutdown-soc - current-soc) < limit)
				then use old SoC.
- qcom,adjust-soc-low-threshold : The low threshold for when the BMS algorithm
			starts adjusting. If the estimated SoC is not below
			this percentage, do not adjust.
- qcom,ocv-voltage-low-threshold-uv : The low voltage threshold for the
			"flat portion" of the discharge curve. The bms will not
			accept new ocvs between these thresholds.
- qcom,ocv-voltage-high-threshold-uv : The high voltage threshold for
			the "flat portion" of the discharge curve.
			The bms will not accept new ocvs between these
			thresholds.
- qcom,low-soc-calculate-soc-threshold : The SoC threshold for when
			the periodic calculate_soc work speeds up. This ensures
			SoC is updated in userspace constantly when we are near
			shutdown.
- qcom,low-voltage-threshold : The battery voltage threshold in micro-volts for
			when the BMS tries to wake up and hold a wakelock to
			ensure a clean shutdown.
- qcom,low-voltage-calculate-soc-ms : The time period between subsequent
			SoC recalculations when the current voltage is below
			qcom,low-voltage threshold. This takes precedence over
			qcom,low-soc-calculate-soc-ms.
- qcom,low-soc-calculate-soc-ms : The time period between subsequent
			SoC recalculations when the current SoC is below
			qcom,low-soc-calculate-soc-threshold. This takes
			precedence over qcom,calculate-soc-ms.
- qcom,calculate-soc-ms : The time period between subsequent SoC
			recalculations when the current SoC is above or equal
			qcom,low-soc-calculate-soc-threshold.
- qcom,chg-term-ua : current in micro-amps when charging is considered done.
			As soon as current passes this point, charging is
			stopped.
- qcom,batt-type: Type of battery used. This is an integer that corresponds
			to the enum defined in
			include/linux/mfd/pm8xxx/batterydata-lib.h
- qcom,high-ocv-correction-limit-uv: how much the bms will correct OCV when
			voltage is above the flat portion of the discharge
			curve.
- qcom,low-ocv-correction-limit-uv: how much the bms will correct OCV when
			voltage is below the flat portion of the discharge
			curve.
- qcom,hold-soc-est: if the voltage-based estimated SoC is above this percent,
			the BMS will clamp SoC to be at least 1.
- qcom,tm-temp-margin: if the pmic die temperature changes by more than this
			value, recalibrate the ADCs. The unit of this property
			is in millidegrees celsius.
- qcom,min-fcc-learning-soc: An interger value which defines the minimum SOC
			to start FCC learning. This is applicable only if
			FCC learning is enabled.
- qcom,min-fcc-ocv-pc:	An interger value which defines the minimum PC-lookup
			(OCV) to start FCC learning. This is applicable only if
			FCC learning is enabled.
- qcom,min-fcc-learning-samples: An interger value which defines the minimum
			number of the FCC measurement cycles required to
			generate an FCC update. This is applicable only
			if the FCC learning is enabled.
- qcom,fcc-resolution:	An integer which defines the fcc resolution used
			for storing the FCC(mAh) in the 8-bit BMS register.
			For example - A value of 10 indicates:
			FCC value (in mAh) = (8-bit register value) * 10.
- qcom,bms-vadc: Corresponding VADC device's phandle.
- qcom,bms-iadc: Corresponding IADC device's phandle.

Parent node optional properties:
- qcom,ignore-shutdown-soc: A boolean that controls whether BMS will
			try to force the startup SoC to be the same as the
			shutdown SoC. Defining it will make BMS ignore the
			shutdown SoC.
- qcom,use-voltage-soc : A boolean that controls whether BMS will use
			voltage-based SoC instead of a coulomb counter based
			one. Voltage-based SoC will not guarantee linearity.
- qcom,use-external-rsense : A boolean that controls whether BMS will use
			an external sensor resistor instead of the default
			RDS of the batfet.
- qcom,use-ocv-thresholds : A boolean that controls whether BMS will take
			new OCVs only between the defined thresholds.
- qcom,enable-fcc-learning: A boolean that defines if FCC learning is enabled.
- qcom,bms-adc_tm: Corresponding ADC_TM device's phandle to set recurring
			measurements and receive notifications for
			die_temperature and vbatt.

qcom,batt-pres-status node required properties:
- reg : offset and length of the PMIC SMBB battery interface BATT_PRES_STATUS
		register.

qcom,soc-storage-reg node required properties:
- reg : address and length of the spare PMIC register that the BMS will store
		shutdown SoC in.

qcom,bms-iadc node required properties:
- reg : offset and length of the PMIC peripheral register map.

qcom,bms-bms node required properties:
- reg : offset and length of the PMIC peripheral register map.
- interrupts : the interrupt mappings.
		The format should be
		<slave-id peripheral-id interrupt-number>.
- interrupt-names : names for the mapped bms interrupt
		The following interrupts are required:
		0 : vsense_for_r
		1 : vsense_avg
		2 : sw_cc_thr
		3 : ocv_thr
		4 : charge_begin
		5 : good_ocv
		6 : ocv_for_r
		7 : cc_thr

Example:
pm8941_bms: qcom,bms {
	spmi-dev-container;
	compatible = "qcom,qpnp-bms";
	#address-cells = <1>;
	#size-cells = <1>;
	status = "disabled";

	qcom,r-sense-uohm = <10000>;
	qcom,v-cutoff-uv = <3400000>;
	qcom,max-voltage-uv = <4200000>;
	qcom,r-conn-mohm = <18>;
	qcom,shutdown-soc-valid-limit = <20>;
	qcom,ocv-voltage-low-threshold-uv = <3650000>;
	qcom,ocv-voltage-high-threshold-uv = <3750000>;
	qcom,adjust-soc-low-threshold = <15>;
	qcom,low-soc-calculate-soc-threshold = <15>;
	qcom,low-voltage-threshold = <3420000>;
	qcom,low-voltage-calculate-soc-ms = <1000>;
	qcom,low-soc-calculate-soc-ms = <5000>;
	qcom,calculate-soc-ms = <20000>;
	qcom,chg-term-ua = <100000>;
	qcom,batt-type = <0>;
	qcom,low-ocv-correction-limit-uv = <100>;
	qcom,high-ocv-correction-limit-uv = <50>;
	qcom,hold-soc-est = <3>;
	qcom,tm-temp-margin = <5000>;
	qcom,battery-data = <&mtp_batterydata>;
	qcom,bms-vadc = <&pm8941_vadc>;
	qcom,bms-iadc = <&pm8941_iadc>;
	qcom,bms-adc_tm = <&pm8941_adc_tm>;

	qcom,batt-pres-status@1208 {
		reg = <0x1208 0x1>;
	}

	qcom,bms-iadc@3800 {
		reg = <0x3800 0x100>;
	};

	qcom,bms-bms@4000 {
		reg = <0x4000 0x100>;
		interrupts =	<0x0 0x40 0x0>,
				<0x0 0x40 0x1>,
				<0x0 0x40 0x2>,
				<0x0 0x40 0x3>,
				<0x0 0x40 0x4>,
				<0x0 0x40 0x5>,
				<0x0 0x40 0x6>,
				<0x0 0x40 0x7>;

		interrupt-names = "vsense_for_r",
				  "vsense_avg",
				  "sw_cc_thr",
				  "ocv_thr",
				  "charge_begin",
				  "good_ocv",
				  "ocv_for_r",
				  "cc_thr";
	};
};
